import os
import time
import sys
import win32gui
import win32process
import win32con
import psutil
import logging

# 获取用户文档文件夹路径
DOCUMENTS_DIR = os.path.expanduser("~\\Documents")

# targets.txt 文件路径 (在文档文件夹中)
TARGETS_FILE = os.path.join(DOCUMENTS_DIR, "auto_maximize_targets.txt")

# 日志文件路径 (在文档文件夹中，固定文件名)
LOG_FILENAME = "auto_maximize_log.txt"
LOG_FILE_PATH = os.path.join(DOCUMENTS_DIR, LOG_FILENAME)

# 自定义日志处理器，实现倒序写入
class PrependingFileHandler(logging.FileHandler):
    def __init__(self, filename, mode='a', encoding=None, delay=False):
        super().__init__(filename, mode, encoding, delay)

    def emit(self, record):
        try:
            msg = self.format(record)
            # 读取现有内容
            existing_content = ""
            if os.path.exists(self.baseFilename):
                with open(self.baseFilename, 'r', encoding=self.encoding) as f:
                    existing_content = f.read()
            # 新日志在前面，旧日志在后面
            with open(self.baseFilename, 'w', encoding=self.encoding) as f:
                f.write(msg + '\n' + existing_content)
        except Exception:
            self.handleError(record)

# 配置日志
logger = logging.getLogger('AutoMaximizeLogger')
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")

# 控制台处理器
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

# 自定义文件处理器
if not os.path.exists(DOCUMENTS_DIR):
    os.makedirs(DOCUMENTS_DIR) #确保文档目录存在
file_handler = PrependingFileHandler(LOG_FILE_PATH, encoding='utf-8')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# 最大化按钮样式标志
WS_MAXIMIZEBOX = 0x00010000


def load_targets(file_path):
    """
    从 targets.txt 读取每行路径，返回可执行文件名列表
    """
    exe_names = []
    if not os.path.exists(file_path):
        logger.error(f"未找到 targets 文件: {file_path}")
        return exe_names
    with open(file_path, "r", encoding="utf-8") as f:
        for line in f:
            path = line.strip()
            if not path or path.startswith("#"):
                continue
            exe = os.path.basename(path)
            exe_names.append(exe)
    return exe_names


def enum_windows():
    hwnds = []
    win32gui.EnumWindows(lambda h, lst: lst.append(h) or True, hwnds)
    return hwnds


def get_pid_from_hwnd(hwnd):
    try:
        _, pid = win32process.GetWindowThreadProcessId(hwnd)
        return pid
    except Exception:
        return None


def main():
    logger.info(f"程序启动，日志文件位于: {LOG_FILE_PATH}")
    logger.info(f"将从以下路径加载目标程序列表: {TARGETS_FILE}")
    # 加载监控目标
    exe_targets = load_targets(TARGETS_FILE)
    if not exe_targets:
        logger.error("错误: 目标列表为空或 targets.txt 文件未找到。请在 targets.txt 中添加可执行文件路径。")
        return
    logger.info(f"监控开始，目标程序: {exe_targets}")
    seen_pids = set()
    while True:
        for proc in psutil.process_iter(["name", "pid"]):
            name = proc.info["name"]
            pid = proc.info["pid"]
            if name not in exe_targets:
                continue
            if pid in seen_pids:
                continue
            # 找到新启动进程，枚举窗口
            for hwnd in enum_windows():
                if not win32gui.IsWindowVisible(hwnd):
                    continue
                if get_pid_from_hwnd(hwnd) != pid:
                    continue
                if win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE) & WS_MAXIMIZEBOX:
                    win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
                    logger.info(f"{name} (PID={pid}) 窗口已最大化。")
                    seen_pids.add(pid)
                    break
        time.sleep(0.6)


if __name__ == "__main__":
    main()
